
 #  Basic example blacklist class. This class takes a text file with regex
 #  rules against which URL's are tested.
 #  The default file location is (base_path)/blacklist.txt
 # 

class ContentRewriter:

	def rewriteGadgetView(self, gadget, gadgetView):
		#  Dont rewrite content if the spec is unavailable

		requires = gadget.getRequires();
		if (requires.has_key(ContentRewriteFeature.REWRITE_TAG)):
			#  Store the feature in the spec so we dont keep parsing it

			rewriteFeature = ContentRewriteFeature();
			rewriteFeature.createRewriteFeature(gadget);
		else:
			return False;
		
		if (not (rewriteFeature.isRewriteEnabled())):
			return False;
		
		if (ContentRewriteFeature.PROXY_URL != None):
			defaultTags = ContentRewriteFeature.defaultHTMLTags();
			htmlTags = None;
			if (len(rewriteFeature.getTagsParam()) > 0):
				for tag in rewriteFeature.getTagsParam():
					if (defaultTags.has_key(tag)):
						htmlTags[tag] = defaultTags[tag];
					
			else:
				htmlTags = defaultTags;
			
		
		gadgetView.setRewrittenContent(self.rewrite(gadgetView.getContent(), htmlTags, rewriteFeature.getExcludeParam(), rewriteFeature.getIncludeParam(), Config.get('web_prefix') + ContentRewriteFeature.PROXY_URL, gadget.getId().getURI(), rewriteFeature.getTagsParam()));
		return True;
	

	def rewriteRequest(self, request):
		if (not (request.isPost()) and (self.isCSS(request.getContentType()) or self.isHTML(request.getContentType()))):
			if (self.isCSS(request.getContentType())):
				htmlTags = ContentRewriteFeature.styleRegex();
			else:
				htmlTags = ContentRewriteFeature.defaultHTMLTags();
			
			content = request.getResponseContent();
			request.setResponseContent(self.rewrite(content, htmlTags, '//', '/(.*)/', Config.get('web_prefix') . ContentRewriteFeature.PROXY_URL, request.getUrl()));
		
		return False;

 
	

	def rewrite(self, content, htmlTags, excRegex, incRegex, prefix, gadgetUrl, tagsParam = None):
		original = content;
		toReplace = [];
		toMatch = [];
		if (htmlTags != None):
			for rx in htmlTags:
				matchTemp = None;
				#[TODO]
				#@preg_match_all($rx, $content, $matchTemp[0]);
				matchTemp = content.finditer(rx);

				temp = [];

				for m in matchTemp:
					temp.appent(m.group());

				#if (! empty($matchTemp[0][0])) {
				#	$matchTemp[0][1] = $matchTemp[0][2];
				#	unset($matchTemp[0][2]);
				#	$toMatch = array_merge($toMatch, $matchTemp);
				

		count = 0;
		
		for match in toMatch:
			size = len(match[1]);
			#for ($i = 0; $i < $size; $i ++) {
			#	$url = trim($match[1][$i]);
			#	if (($excRegex != '# ' && @preg_match($excRegex, $url) != 0) || 
			#		($incRegex != '# ' && @preg_match($incRegex, $url) == 0)) {
			#		continue;
			#	}
			#	$toReplace[$count]['original'] = $match[0][$i];
			#	$toReplace[$count]['url'] = $url;
			#	if (self.isRelative($url)) {
			#		$lPosition = strrpos($gadgetUrl, "/");
			#		$gadgetUrl = substr($gadgetUrl, 0, $lPosition + 1);
			#		$url = $gadgetUrl . $url;
			#	}
			#	$toReplace[$count]['new'] = $prefix . urlencode($url);
			#	$count ++;
			#}
		#}

		if (len(toReplace) > 0):
			for target in toReplace:
				tagTemp = target['url'].raplace(target['new'], target['original']);
				content = target['original'].replace(tagTemp, content);
			
		else:
			return original;
		
		return content;
	

	


	def __isRelative_(self, url):
		# return ! (strpos($url, "http://") !== false);
		return not ((url.find("http://") != -1));
	

	def isHTML(self, mime):
		if (mime == None):
			return False;

		return (mime.lower().find('html') != -1);
	

	def isCSS(self, mime):
		if (mime == None):
			return False;
		
		return (mime.lower().find('css') != -1);
	


 
class ContentRewriteFeature:
	REWRITE_TAG = "content-rewrite";
	INCLUDE_URLS = "include-urls";
	EXCLUDE_URLS = "exclude-urls";
	INCLUDE_TAGS = "include-tags";
	PROXY_URL = "/gadgets/proxy?url=";

	def __init__(self):
		self.__includeAll_ = False;
		self.__includeNone_ = False;
		self.__includeParam_;
		self.__excludeParam_;
		self.__tagsParam_;

	def createRewriteFeature(self, gadget):
		requires = gadget.getRequires();
		if (not (requires.has_key(ContentRewriteFeature.REWRITE_TAG))):
			return;
		
		rewriteFeature = requires[ContentRewriteFeature.REWRITE_TAG];
		rewriteParams = rewriteFeature.getParams();
		if (rewriteParams.has_key(ContentRewriteFeature.INCLUDE_URLS)):
			self.includeParam = self.normalizeParam(rewriteParams[ContentRewriteFeature.INCLUDE_URLS], '//');
		else:
			self.includeParam = '//';
		
		if (rewriteParams.has_key(ContentRewriteFeature.EXCLUDE_URLS)):
			self.excludeParam = self.normalizeParam(rewriteParams[ContentRewriteFeature.EXCLUDE_URLS], '//');
		else:
			self.excludeParam = '//';
		
		if (rewriteParams.has_key(ContentRewriteFeature.INCLUDE_TAGS)):
			self.tagsParam = rewriteParams[ContentRewriteFeature.INCLUDE_TAGS];
			self.tagsParam = self.tagsParam.split(',');
		else:
			self.tagsParam = {};
		
		if (self.excludeParam == '.*' or self.includeParam == None):
			self.includeNone = True;
		
		if (self.includeParam == '.*' or self.excludeParam == None):
			self.includeAll = True;
		

	def createDefaultRewriteFeature(self, gadget):
		self.includeParam = '/.*/';
		self.includeAll = True;
	

	def normalizeParam(self, paramValue, defaultVal):
		if (len(paramValue) == 0):
			return defaultVal;
		
		if (paramValue[0] != '/'):
			return '/' + paramValue + '/';
		else:
			return paramValue;
		

	def isRewriteEnabled(self):
		return not (self.includeNone);
	

	def shouldRewriteURL(self, url):
		if (self.includeNone):
			return False;
		else:
			if (self.includeAll):
				return True;
			else:
				if (preg_match(self.includeParam, url) != 0):
					return (self.excludeParam != None and preg_match(self.excludeParam, url) != 0);
				
		return False;
	

	def shouldRewriteTag(self, tag):
		if (tag != None):
			return self.tagsParam.has_key(tag.lower());
		
		return False;
	

	@staticmethod
	def defaultHTMLTags():
		return {'img' : '/\<img[^\>]*?src\=(\'|\")(.*?)\1/', 
				'link' : '/\<link[^\>]*?href\=(\'|\")(.*?)\1/', 
				'embed' : '/\<embed[^\>]*?src\=(\'|\")(.*?)\1/', 
				'script' : '/\<script[^\>]*?src\=(\'|\")(.*?)\1/', 
				'style' : '/url\(\s*(\'|\"|)([^\'\"]*?)(\'|\"|)\s*\)/'};
	

	@staticmethod
	def styleRegex():
		return {'css' : '/url\(\s*(\'|\"|)([^\'\"]*?)(\'|\"|)\s*\)/'};
	

	def isTagIncluded(self, tag):
		if (len(self.tagsParam) == 0):
			return False;

		return self.getTagsParam().has_key(tag);

	def getExcludeParam(self):
		return self.excludeParam;

	def getIncludeParam(self):
		return self.includeParam;

	def getIncludeAll(self):
		return self.includeAll;

	def getIncludeNone(self):
		return self.includeNone;

	def getTagsParam(self):
		return self.tagsParam;

	def setExcludeParam(self, excludeParam):
		self.excludeParam = excludeParam;

	def setIncludeParam(self, includeParam):
		self.includeParam = includeParam;

	def setIncludeAll(self, includeAll):
		self.includeAll = includeAll;

	def setIncludeNone(self, includeNone):
		self.includeNone = includeNone;

	def setTagsParam(self, tagsParam):
		self.tagsParam = tagsParam;
